package app

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/json"
	"log"
	"os"
	"path/filepath"
)

type Host struct {
	IP       string `json:"ip"`
	Username string `json:"username"`
	Password string `json:"password"`  // 加密存储
	Port     int    `json:"port"`
}

type StorageService struct {
	configPath string
	key        []byte
	logger     *log.Logger
}

func NewStorageService() *StorageService {
	return &StorageService{
		configPath: filepath.Join("configs", "hosts.json"),
		key:        []byte("this-is-a-32-byte-encryption-key"), // 临时测试用32字节密钥
		logger:     log.New(os.Stderr, "[STORAGE] ", log.LstdFlags|log.Lshortfile),
	}
}

func (s *StorageService) SaveHosts(hosts []Host) error {
	encryptedData, err := s.encryptData(hosts)
	if err != nil {
		return err
	}
	return os.WriteFile(s.configPath, encryptedData, 0600)
}

func (s *StorageService) LoadHosts() ([]Host, error) {
	data, err := os.ReadFile(s.configPath)
	if err != nil {
		return nil, err
	}
	return s.decryptData(data)
}

func (s *StorageService) encryptData(hosts []Host) ([]byte, error) {
	plainText, err := json.Marshal(hosts)
	if err != nil {
		return nil, err
	}

	block, err := aes.NewCipher(s.key)
	if err != nil {
		return nil, err
	}

	gcm, err := cipher.NewGCM(block)
	if err != nil {
		return nil, err
	}

	nonce := make([]byte, gcm.NonceSize())
	if _, err = rand.Read(nonce); err != nil {
		return nil, err
	}

	return gcm.Seal(nonce, nonce, plainText, nil), nil
}

func (s *StorageService) decryptData(cipherText []byte) ([]Host, error) {
	block, err := aes.NewCipher(s.key)
	if err != nil {
		return nil, err
	}

	gcm, err := cipher.NewGCM(block)
	if err != nil {
		return nil, err
	}

	nonceSize := gcm.NonceSize()
	nonce, cipherText := cipherText[:nonceSize], cipherText[nonceSize:]

	plainText, err := gcm.Open(nil, nonce, cipherText, nil)
	if err != nil {
		return nil, err
	}

	var hosts []Host
	err = json.Unmarshal(plainText, &hosts)
	return hosts, err
}